19.4 驯服危险的深层嵌套

文章目录
  1. 1. 一些避免深层嵌套的方法
    1. 1.1. 对于嵌套的 if 语句
      1. 1.1.1. 通过拆分嵌套(需要重复检测某些条件)来减少嵌套层次
        1. 1.1.1.1. 拆分图示
      2. 1.1.2. 用 break 块来简化循环里的嵌套 if
      3. 1.1.3. 把嵌套 if 转换为一组 if-then-else 语句
      4. 1.1.4. 把嵌套 if 转换成 case 语句
    2. 1.2. 其他
      1. 1.2.1. 将深层嵌套的代码抽取为单独的子程序
      2. 1.2.2. 使用一种更加面向对象的方法
      3. 1.2.3. 重新设计深层嵌套的代码
  2. 2. 总结

建议避免超过 3~4 层以上的嵌套

一些避免深层嵌套的方法

对于嵌套的 if 语句

通过拆分嵌套(需要重复检测某些条件)来减少嵌套层次

toExemplify-book

作为代价,你必须要容忍使用一个更加复杂的判断。但如果可以大幅减少桥嵌套层次的话,值得考虑

拆分图示

这个大的嵌套:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
graph LR
Z(start)
Z --> A{A?}
A --> |True| exeA(执行 A part)
exeA --> B{B?}
A --> |False| NA(跳过 A part)
B --> |True| exeB(执行 B part)
exeB --> C{C?}
B --> |False| NB(跳过 B part)
C --> |True| exeC(执行 C part)
exeC --> D{D?}
C --> |False| NC(跳过 C part)
D --> |True| exeD(执行 D part)
D --> |False| ND(跳过 D part)

拆分成两个小嵌套 (第二个嵌套中要重复检测在第一个嵌套里的条件)

1
2
3
4
5
6
7
8
graph LR
Z(start)
Z --> A{A?}
A --> |True| exeA(执行 A part)
exeA --> B{B?}
A --> |False| NA(跳过 A part)
B --> |True| exeB(执行 B part)
B --> |False| NB(跳过 B part)
1
2
3
4
5
6
7
8
graph LR
Z(start)
Z --> |增加判断| C{ A? && B? && C?}
C --> |True| exeC(执行 C part)
exeC --> D{D?}
C --> |False| NC(跳过 C part)
D --> |True| exeD(执行 D part)
D --> |False| ND(跳过 D part)

交叉参考 17.3节[[错误处理和 goto]]

用 break 块来简化循环里的嵌套 if

toReRead

注意,在 python 中,break cannot be used to break out of an if - it can only break out of loops. (不过你也可以用 return 来实现这一功能)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def deep_loop(s):
if 1 <= s:
print('1')
if 2 <= s:
print('2')
if 3 <= s:
print('3')
if 4 <= s:
print('4')
def use_break(s):
for i in range(1):
if s < 1:
break
print('1')
if s < 2:
break
print('2')
if s < 3:
break
print('3')
if s < 4:
break
print('4')

while True:
n = input('n:')
n = int(n)
print('deep_loop:')
deep_loop(n)
print('use_break:')
use_break(n)

不过 python 中有 elif,也比较方便了

其他语言未尝试,toExemplify-book

注意,这一技巧很不常见,要和团队商量,团队熟悉、接受后才能使用

把嵌套 if 转换为一组 if-then-else 语句

toNote

类似于 python 中 elif

把嵌套 if 转换成 case 语句

在一些情况下可以利用 case 语句重写,特别是含有整数的判断

toNote

其他

将深层嵌套的代码抽取为单独的子程序

当嵌套是由于条件和迭代二者共同产生的,这么做特别有效。把 if-then-else 分支保留在主循环中(以便显示决策的分支走向),然后将各分支中的复杂语句提取为单独的子程序,再调用

toExemplify-book —— important!

使用一种更加面向对象的方法

toExemplify-book —— important!

这个还不熟悉——但隐约有些懂了

重新设计深层嵌套的代码

复杂的代码表明你还没有充分理解你的程序,所以无法简化它

toNote

总结

有些技术在其他章节

toNote